package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.MessageConstant;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.MessageTypeEnum;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CurrentUserHolder;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.system.dto.*;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SmsService;
import com.nineclock.system.service.SysCompanyService;
import com.nineclock.system.utils.HxImManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private SysCompanyUserMapper companyUserMapper;
    @Autowired
    RedisTemplate<String,String> redisTemplate;
    @Autowired
    SysRoleMapper sysRoleMapper;
    @Autowired
    SysCompanyUserRoleMapper userRoleMapper;

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {

        if (sysCompanyDTO==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);
        if (sysCompany==null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setName(sysCompanyDTO.getName());

        sysCompanyMapper.updateById(sysCompany);
    }


    @Override
    public SysCompanyDTO queryCompanyInfo() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);

        if(sysCompany == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        return BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);
    }

    @Autowired
    OSS oss;
    @Autowired
    OssProperties ossProperties;

    @Override
    public String uploadCompanyLogo(MultipartFile file) throws IOException {
        //类型大小不合适不允许上传
        if (file==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        String contentType = file.getContentType();
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(contentType)){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        if (file.getSize()>NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        String uuid = UUIDUtils.getUUID();
        String originalFilename = file.getOriginalFilename();
        //获取最后一个点所在的索引
        int index = originalFilename.lastIndexOf(".");
        String substring = originalFilename.substring(index);
        String fileName=uuid+substring;

        // 图片上传( 存储空间名称 ， 文件名， 文件流对象 )
        oss.putObject(ossProperties.getBucketName(),fileName,file.getInputStream());
        String host = ossProperties.getHost();
//      替换%s的值
        String imgPath=String.format(host,ossProperties.getBucketName())+ fileName;
        return imgPath;
    }

    @Override
    public SysCompanyUserDTO getCurrentAdmin() {
        SysCompanyUser sysCompanyUser = companyUserMapper.selectCurrentAdmin(CurrentUserHolder.get().getCompanyId());

        if(sysCompanyUser == null){
            log.error("[系统微服务] - 查询当前企业ID: {}, 未查询到主管理员", CurrentUserHolder.get().getCompanyId());
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        return BeanHelper.copyProperties(sysCompanyUser, SysCompanyUserDTO.class);
    }

    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {
//        参数合法性
        if(sysChangeMainManagerDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

//        获取当前新管理员的数据，判定是否存在
        Long companyId = CurrentUserHolder.get().getCompanyId();

        LambdaQueryWrapper<SysCompanyUser> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getCompanyId,companyId);
        queryWrapper.eq(SysCompanyUser::getEnable,1);
        queryWrapper.eq(SysCompanyUser::getId,sysChangeMainManagerDTO.getUserId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(queryWrapper);

        if(companyUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
//        较验传递的手机验证码是否正确
        String key=SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX+companyUser.getMobile();
        String redisCode = redisTemplate.boundValueOps(key).get();

        if (redisCode==null||!redisCode.equals(sysChangeMainManagerDTO.getCode())){
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }
//        解绑原有的系统管理员与员工的关系-》删除
        LambdaQueryWrapper<SysRole> roleLambdaQueryWrapper=new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.eq(SysRole::getCompanyId,companyId);
        roleLambdaQueryWrapper.eq(SysRole::getRoleName,"ROLE_ADMIN_SYS");

        SysRole sysRole = sysRoleMapper.selectOne(roleLambdaQueryWrapper);

        //删除原管理员关系
        LambdaQueryWrapper<SysCompanyUserRole> companyUserRoleQw = new LambdaQueryWrapper<>();
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyId, companyId);
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyUserId, CurrentUserHolder.get().getCompanyUserId());
        companyUserRoleQw.eq(SysCompanyUserRole::getRoleId, sysRole.getId());
        userRoleMapper.delete(companyUserRoleQw);

        //添加信息的关系
        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyId(companyId);
        companyUserRole.setRoleId(sysRole.getId());
        companyUserRole.setCompanyUserId(sysChangeMainManagerDTO.getUserId());

        userRoleMapper.insert(companyUserRole);

    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        LambdaQueryWrapper<SysCompany> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.like(SysCompany::getName,keyword);

        List<SysCompany> companyList = sysCompanyMapper.selectList(queryWrapper);
        if(CollectionUtil.isNotEmpty(companyList)){
            return BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
        }
        return null;
    }

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private HxImManager hxImManager;

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {
        log.info(sysApplyJoinCompanyUserDTO.getUserName()+" 申请加入企业 " +sysApplyJoinCompanyUserDTO.getCompanyName());
        //参数校验
        if(sysApplyJoinCompanyUserDTO == null || sysApplyJoinCompanyUserDTO.getUserId() == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //更新用户
        SysUser sysUser = userMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());
        if(sysUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        sysUser.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        sysUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        sysUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysUser.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        log.info("更新用户信息 "+ sysApplyJoinCompanyUserDTO.getUserName());
        userMapper.updateById(sysUser);

        //如果提交企业ID，说明在做申请加入企业操作
        if(sysApplyJoinCompanyUserDTO.getCompanyId() != null){

            SysCompanyUser sysCompanyUser = new SysCompanyUser();
            sysCompanyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
            sysCompanyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());
            sysCompanyUser.setEnable((short)0);//未审核
            sysCompanyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl());
            sysCompanyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
            sysCompanyUser.setPost(sysApplyJoinCompanyUserDTO.getPost());
            sysCompanyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
            sysCompanyUser.setUserId(sysApplyJoinCompanyUserDTO.getUserId());
            sysCompanyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());
            sysCompanyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());

            log.info("保存企业员工信息 ");
            companyUserMapper.insert(sysCompanyUser);
        }

        // 发送消息到MQ , 推送消息,通知管理员
        SysCompanyUser currentAdmin = companyUserMapper.selectCurrentAdmin(sysApplyJoinCompanyUserDTO.getCompanyId());

        if (currentAdmin!=null){
            NcMessage message=new NcMessage();

            message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType());
            message.setCreateTime(new Date());
            message.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId()+"");
            message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle());
            message.setContent(sysUser.getUsername()+" 申请加入企业，请及时审批。");
            message.setUseStatus(0);
//            消息作用域
            message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience());
            message.setTargets(Arrays.asList(currentAdmin.getMobile()));

//            审批状态
            message.setApproveStatue(0);
            message.setApplyUserId(sysUser.getId());
            message.setApplyUsername(sysUser.getUsername());

            message.setApproveUserId(currentAdmin.getId());
            message.setApproveUsername(currentAdmin.getUserName());

            rocketMQTemplate.convertAndSend("messagePushTopic",message);

            //注册用户到环信云, 用于APP端用户之间的及时通讯
            sysUser.setPassword("123456");
            sysUser.setUsername(sysUser.getMobile());
            hxImManager.registerUser2HuanXing(sysUser);
            log.info("注册用户到环信云");
        }
    }

    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
//        根据企业Id,员工id查询，员工信息
        LambdaQueryWrapper<SysCompanyUser> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        queryWrapper.eq(SysCompanyUser::getUserId,sysAllowedJoinCompanyUserDTO.getApplyUserId());
        SysCompanyUser companyUser = companyUserMapper.selectOne(queryWrapper);

        if (companyUser!=null){
            companyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());
            companyUser.setEnable((short) (sysAllowedJoinCompanyUserDTO.getApproved()?1:0));

            companyUserMapper.updateById(companyUser);

//            如果审核通过，发送消息，修改状态
            if (sysAllowedJoinCompanyUserDTO.getApproved()){
                rocketMQTemplate.convertAndSend("allowedJoinCompanyTopic",sysAllowedJoinCompanyUserDTO.getNotifyMsgId());

//                构造通过消息，向用户发送
                NcMessage message=new NcMessage();

                message.setApplyUserId(sysAllowedJoinCompanyUserDTO.getApplyUserId());
                message.setApplyUsername(companyUser.getUserName());
                message.setMessageType(MessageConstant.COMPANY_APPLY_PASS);
                message.setContent(companyUser.getUserName() + " 加入企业请求,申请通过!");

                message.setApproveUserId(CurrentUserHolder.get().getId());
                message.setApproveUsername(CurrentUserHolder.get().getUsername());
                message.setTargets(Collections.singletonList(companyUser.getMobile()));

                log.info("发送消息到MQ , 推送审核通过的消息给系统管理员");
                rocketMQTemplate.convertAndSend("messagePushTopic",message);
            }
        }
    }

    @Override
    public List<SysCompanyDTO> queryCompanyListByUserId(Long userId) {
        if(userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<SysCompany> companyList=companyUserMapper.queryCompanyListByUserId(userId);
        if(CollectionUtil.isEmpty(companyList)){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        return BeanHelper.copyWithCollection(companyList,SysCompanyDTO.class);
    }
}
